<!DOCTYPE HTML PUBLIC "-//ORA//DTD CD HTML 3.2//EN">
<HTML>
<HEAD>
<TITLE>[Chapter 11] 11.4 Menus and Choices</TITLE>
<META NAME="author" CONTENT="Pat Niemeyer and Josh Peck">
<META NAME="date" CONTENT="Tue Jul 22 19:01:08 1997">
<META NAME="form" CONTENT="html">
<META NAME="metadata" CONTENT="dublincore.0.1">
<META NAME="objecttype" CONTENT="book part">
<META NAME="otheragent" CONTENT="gmat dbtohtml">
<META NAME="publisher" CONTENT="O'Reilly &amp; Associates, Inc.">
<META NAME="source" CONTENT="SGML">
<META NAME="subject" CONTENT="Java">
<META NAME="title" CONTENT="Exploring Java">
<META HTTP-EQUIV="Content-Script-Type" CONTENT="text/javascript">
</HEAD>
<body vlink="#551a8b" alink="#ff0000" text="#000000" bgcolor="#FFFFFF" link="#0000ee">

<DIV CLASS=htmlnav>
<H1><a href='index.htm'><IMG SRC="gifs/smbanner.gif"
     ALT="Exploring Java" border=0></a></H1>
<table width=515 border=0 cellpadding=0 cellspacing=0>
<tr>
<td width=172 align=left valign=top><A HREF="ch11_03.htm"><IMG SRC="gifs/txtpreva.gif" ALT="Previous" border=0></A></td>
<td width=171 align=center valign=top><B><FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">Chapter 11<br>Using and Creating GUI Components</FONT></B></TD>
<td width=172 align=right valign=top><A HREF="ch11_05.htm"><IMG SRC="gifs/txtnexta.gif" ALT="Next" border=0></A></td>
</tr>
</table>

&nbsp;
<hr align=left width=515>
</DIV>
<DIV CLASS=sect1>
<h2 CLASS=sect1><A CLASS="TITLE" NAME="EXJ-CH-11-SECT-5">11.4 Menus and Choices</A></h2>

<P CLASS=para>
<A NAME="CH10.MENU1"></A> <A NAME="CH10.MENU2"></A><A NAME="CH10.MENU3"></A>
 
A <tt CLASS=literal>Menu</tt> is a standard, pull-down menu with a fixed
name. Menus can hold other menus as submenu items, letting you
implement complex menu structures. Menus come with several
restrictions; they must be attached to a menu bar, and the menu bar
can be attached only to a <tt CLASS=literal>Frame</tt> (or another
menu). You can't stick a <tt CLASS=literal>Menu</tt> at an arbitrary
position within a container. A top-level <tt CLASS=literal>Menu</tt> has a
name that is always visible in the menu bar. (An important exception to
these rules is the <tt CLASS=literal>PopupMenu</tt>, which we'll
describe in the next section.)

<P CLASS=para>
A <tt CLASS=literal>Choice</tt> is an item that lets you choose
from a selection of alternatives. If this sounds like a menu,
you're right. Choices are free-spirited relatives of menus. A
<tt CLASS=literal>Choice</tt> item can be positioned anywhere, in any kind
of container. It looks something like a button, with the current
selection as its label. When you press the mouse button on a choice,
it unfurls to show possible selections.

<P CLASS=para>
Both menus and choices send action events when an item is
selected. We'll create a little example that illustrates choices
and menus and demonstrates how to work with the events they
generate. Since a <tt CLASS=literal>Menu</tt> has to be placed in the menu
bar of a <tt CLASS=literal>Frame</tt>, we'll take this opportunity
to show off a <tt CLASS=literal>Frame</tt> object as
well. <tt CLASS=literal>DinnerMenu</tt> pops up a window containing a
<b>Food</b> choice and a menu of <b>Utensils</b>, as shown in <A HREF="ch11_02.htm#EXJ-CH-11-FIG-2">Figure 11.2</A>. <tt CLASS=literal>DinnerMenu</tt> prints a
message for each selection; choosing <b>Quit</b> from the menu removes the window. Give it a
try.

<DIV CLASS=figure>
<h4 CLASS=figure><A CLASS="TITLE" NAME="EXJ-CH-11-FIG-5">Figure 11.5: The DinnerMenu applet</A></h4>


<p>
<img align=middle src="./figs/je1105.gif" alt="[Graphic: Figure 11-5]" width=503 height=223 border=0>

</DIV>

<DIV CLASS=screen>
<P>
<PRE>
import java.awt.*;
import java.awt.event.*;
import java.util.EventListener;
public class DinnerMenu extends java.applet.Applet { 
    public void init() {
        new DinnerFrame().show();
    }
}
class DinnerFrame extends Frame implements ActionListener, ItemListener {
    DinnerFrame() {
        setTitle("Dinner Helper");
        setLayout( new FlowLayout() );
        add( new Label("Food") );
        Choice c = new Choice ();
        c.addItem("Chinese");
        c.addItem("Italian");
        c.addItem("American");
        c.addItemListener( this );
        add( c );
        Menu menu = new Menu("Utensils");
        menu.add( makeMenuItem("Fork") );
        menu.add( makeMenuItem("Knife") );
        menu.add( makeMenuItem("Spoon") );
        Menu subMenu = new Menu("Hybrid");
        subMenu.add( makeMenuItem("Spork") );
        subMenu.add( makeMenuItem("Spife") );
        subMenu.add( makeMenuItem("Knork") );
        menu.add( subMenu);
        menu.add( makeMenuItem("Quit") );
        MenuBar menuBar = new MenuBar();
        menuBar.add(menu);
        setMenuBar(menuBar);
        pack();
    }
    public void itemStateChanged(ItemEvent e) {
        System.out.println( "Choice set to: " + e.getItem() );
    }
    public void actionPerformed(ActionEvent e) {
        String command = e.getActionCommand();
        if ( command.equals( "Quit" ) )
            dispose();
        else
            System.out.println( "Menu selected: " + e.getActionCommand() );
    }
    private MenuItem makeMenuItem( String name ) {
        MenuItem m = new MenuItem( name );
        m.addActionListener( this );
        return m;
    }
}
</PRE>
</DIV>

<P CLASS=para>
Yes, I know. <b>Quit</b> doesn't belong
in the <b>Utensils</b> menu. If it's
driving you crazy, you can go back and add a
<b>File</b> menu as an exercise when
we're through.

<P CLASS=para>
So what do we have? Well, we've created a new kind of
component called <tt CLASS=literal>DinnerFrame</tt> that implements our
palette of dinner options. We do our set-up work in the
<tt CLASS=literal>DinnerFrame</tt> constructor.
<tt CLASS=literal>DinnerFrame</tt> sets the name on its titlebar with
<tt CLASS=literal>setTitle()</tt>. 
The constructor also handles a few
other miscellaneous details, such as setting the layout manager that
places things side by side in the display area and later, resizing
itself by calling <tt CLASS=literal>pack()</tt>.

<P CLASS=para>
We make an instance of <tt CLASS=literal>Choice</tt> and add three
options to it with its <tt CLASS=literal>addItem()</tt>
method. <tt CLASS=literal>Choice</tt> options are simple
<tt CLASS=literal>String</tt> objects. When one is picked, we get an
action event with an argument that specifies the selected option
name. We can also examine the currently selected item at any time with
the <tt CLASS=literal>Choice</tt>'s
<tt CLASS=literal>getSelectedItem()</tt> method. A
<tt CLASS=literal>Choice</tt> generates an
<tt CLASS=literal>ItemEvent</tt> when a user makes a selection,
so we register the <tt CLASS=literal>DinnerFrame</tt> as an
<tt CLASS=literal>ItemEvent</tt> listener by calling
<tt CLASS=literal>addItemListener()</tt>. (This means we must
also implement the <tt CLASS=literal>ItemListener</tt> interface
and provide an <tt CLASS=literal>itemStateChanged()</tt> method.)
As with any component, we
display the <tt CLASS=literal>Choice</tt> by adding it to our
applet's layout with <tt CLASS=literal>add()</tt>.

<P CLASS=para>
The <tt CLASS=literal>Menu</tt> has a few more moving parts. A
<tt CLASS=literal>Menu</tt> holds
<tt CLASS=literal>MenuItem</tt> objects. A 
simple <tt CLASS=literal>MenuItem</tt> just has a
<tt CLASS=literal>String</tt> as a label. It sends this as an argument in
an action event when it's selected. We can set its font with
<tt CLASS=literal>setFont()</tt>. We can also turn it on or off with
<tt CLASS=literal>setEnabled()</tt>; this
method controls whether the <tt CLASS=literal>MenuItem</tt> is
available or 
not. A <tt CLASS=literal>Menu</tt> object is itself a kind of
<tt CLASS=literal>MenuItem</tt>, and this allows us to use a menu as a
submenu in another menu.

<P CLASS=para>
We construct the <tt CLASS=literal>Menu</tt> with its name and call
its <tt CLASS=literal>add()</tt> method to give it three new 
<tt CLASS=literal>MenuItem</tt> objects. To create the menu
items, we call our own <tt CLASS=literal>makeMenuItem()</tt>
helper method. Next, we repeat this process to
make a new <tt CLASS=literal>Menu</tt> object, <tt CLASS=literal>subMenu</tt>,
and add it as the fourth option. Its name appears as the menu item
along with a little arrow, indicating it's a submenu. When it's
selected, the <tt CLASS=literal>subMenu</tt> menu pops up to the side and
we can select from it. Finally, we add one last simple menu item, to
serve as a <b>Quit</b> option.

<P CLASS=para>
We use a private method, <tt CLASS=literal>makeMenuItem()</tt>,
to create our menu items for us. This method is convenient because,
with menus, every item generates its own events. Therefore, we must
register an <tt CLASS=literal>ActionListener</tt> for every
selection on the menu. Rather than write lots of code, we use a helper
method to register our
<tt CLASS=literal>DinnerFrame</tt>
(<tt CLASS=literal>this</tt>) as the listener for every item. It
should be no 
surprise then, that <tt CLASS=literal>DinnerFrame</tt> must
implement <tt CLASS=literal>ActionListener</tt> and provide an
<tt CLASS=literal>actionPerformed()</tt> method. 

<P CLASS=para>
Now we have the menu; to use it, we have to insert it in a menu bar. A <tt CLASS=literal>MenuBar</tt> holds
<tt CLASS=literal>Menu</tt> objects. We create a
<tt CLASS=literal>MenuBar</tt> and set it as the menu bar for
<tt CLASS=literal>DinnerFrame</tt> with the
<tt CLASS=literal>Frame.setMenuBar()</tt> method. We can then add our menu
to it with <tt CLASS=literal>menuBar.add()</tt>:

<DIV CLASS=screen>
<P>
<PRE>
MenuBar menuBar = new MenuBar();
menuBar.add(menu);
setMenuBar(menuBar);
</PRE>
</DIV>

<P CLASS=para>
Suppose our applet didn't have its own frame? Where could we put
our menu? Ideally, you'd like the applet to be able
to add a menu to the top-level menu bar of the Web browser or applet
viewer. Unfortunately, as of Java 1.1, there is no
standard for doing so. (There are obvious security considerations in
allowing an applet to modify its viewer.) There has been talk of
adding this ability as part of Java Beans, but so far, it's not
possible. 

<P CLASS=para>
One final note about the <tt CLASS=literal>DinnerMenu</tt>
example. As we said in the previous chapter, any
time you use a <tt CLASS=literal>Frame</tt>, and thus create a new
top-level window, you should add code to destroy your frame whenever
the user closes the window with his native window manager. To do so,
you register your frame as a
<tt CLASS=literal>WindowListener</tt>, implement the
<tt CLASS=literal>WindowListener</tt> interface, and provide a
<tt CLASS=literal>windowClosing()</tt> method that calls
<tt CLASS=literal>dispose()</tt>.  
By calling <tt CLASS=literal>dispose()</tt>, we indicate the window
is no longer needed, so that it can release its window-system resources.

</DIV>


<DIV CLASS=htmlnav>

<P>
<HR align=left width=515>
<table width=515 border=0 cellpadding=0 cellspacing=0>
<tr>
<td width=172 align=left valign=top><A HREF="ch11_03.htm"><IMG SRC="gifs/txtpreva.gif" ALT="Previous" border=0></A></td>
<td width=171 align=center valign=top><a href="index.htm"><img src='gifs/txthome.gif' border=0 alt='Home'></a></td>
<td width=172 align=right valign=top><A HREF="ch11_05.htm"><IMG SRC="gifs/txtnexta.gif" ALT="Next" border=0></A></td>
</tr>
<tr>
<td width=172 align=left valign=top>Lists</td>
<td width=171 align=center valign=top><a href="index/idx_0.htm"><img src='gifs/index.gif' alt='Book Index' border=0></a></td>
<td width=172 align=right valign=top>PopupMenus</td>
</tr>
</table>
<hr align=left width=515>

<IMG SRC="gifs/smnavbar.gif" USEMAP="#map" BORDER=0> 
<MAP NAME="map"> 
<AREA SHAPE=RECT COORDS="0,0,108,15" HREF="../javanut/index.htm"
alt="Java in a Nutshell"> 
<AREA SHAPE=RECT COORDS="109,0,200,15" HREF="../langref/index.htm" 
alt="Java Language Reference"> 
<AREA SHAPE=RECT COORDS="203,0,290,15" HREF="../awt/index.htm" 
alt="Java AWT"> 
<AREA SHAPE=RECT COORDS="291,0,419,15" HREF="../fclass/index.htm" 
alt="Java Fundamental Classes"> 
<AREA SHAPE=RECT COORDS="421,0,514,15" HREF="../exp/index.htm" 
alt="Exploring Java"> 
</MAP>
</DIV>

</BODY>
</HTML>
